package com.xiaojie.toolkits;

import cn.hutool.core.util.ZipUtil;
import com.xiaojie.error.FileFormatException;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wangye
 * @classname ZipUtils
 * @date 2021/6/29 10:46
 **/
public class ZipUtils extends ZipUtil {
    /**
     * 压缩文件
     *
     * @param zipPath
     * @param file
     * @param password
     * @param charset
     * @param isSecret
     * @auther wangye
     * @date 2021/6/30
     */
    public static ZipFile zipFileAndEncrypt(String zipPath, File file, String password, String charset, boolean isSecret) {
        ZipFile zipFile = null;
        try {
            //设置参数
            ZipParameters param = new ZipParameters();
            //设置压缩方式,默认是COMP_DEFLATE
            param.setCompressionMethod(CompressionMethod.DEFLATE);
            //设置压缩级别,默认为0（即不压缩）
            param.setCompressionLevel(CompressionLevel.FASTEST);
            zipFile = new ZipFile(zipPath);
            if (isSecret) {
                // 是否密码
                param.setEncryptFiles(true);
                // 加密方式
                param.setEncryptionMethod(EncryptionMethod.AES);
                //设置密码
                zipFile.setPassword(password.toCharArray());
            }
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files!=null){
                    for (File f : files) {
                        if (f.isDirectory()) {
                            zipFile.addFolder(f,param);
                        }else {
                            zipFile.addFile(f,param);
                        }
                    }
                }
            } else {
                zipFile.addFile(file, param);
            }

            Charset c = Charset.forName(charset);
            zipFile.setCharset(c);
        } catch (ZipException e) {
            throw new RuntimeException(e);
        }
        return zipFile;
    }


    /**
     * 文件解压缩
     *
     * @param file
     * @param dest     指定解压缩文件夹位置
     * @param password
     * @param charset
     * @auther wangye
     * @date 2021/6/30
     */
    public static List<File> upZipFile(File file, String dest, String password, String charset) throws ZipException {

        File destDir = new File(dest);
        if (destDir.isDirectory() && !destDir.exists()) {
            destDir.mkdir();
        }

        ZipFile zipFile = new ZipFile(file);
        if (!zipFile.isValidZipFile()) {
            throw new FileFormatException("压缩文件不合法,可能被损坏");
        }

        if (zipFile.isEncrypted()) {
            if (StringUtils.isEmpty(password)) {
                throw new FileFormatException("加密文件，密码为空");
            } else {
                zipFile.setPassword(password.toCharArray());
            }
        }

        zipFile.extractAll(dest);
        List<FileHeader> headerList = zipFile.getFileHeaders();
        List<File> extractedFileList = new ArrayList<>();
        for (FileHeader fileHeader : headerList) {
            if (!fileHeader.isDirectory()) {
                extractedFileList.add(new File(destDir, fileHeader.getFileName()));
            }
        }
        return extractedFileList;
    }
}

